﻿/**
* CRL
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Common;

using System.Data;

using CRL.Core;
using System.Threading.Tasks;
using System.Runtime.InteropServices;

namespace CRL.Data.DBAccess
{
    public partial class DBHelper
    {

        #region 私有方法

        private async Task<int> ExecuteNonQueryAsync(string text, CommandType type)
        {
            var time = DateTime.Now;
            GetOrCreateConn();
            DbCommand cmd = (DbCommand)CreateCmd(text, currentConn);
            cmd.CommandTimeout = 180;
            if (_trans != null)
            {
                cmd.Transaction = _trans as DbTransaction;
            }
            cmd.CommandType = type;
            FillCmdParams(cmd);
            int a = 0;
            try
            {
                a = await cmd.ExecuteNonQueryAsync();
                var ts = DateTime.Now - time;
                ExecuteTime += ts.TotalMilliseconds;
            }
            catch (DbException ero)
            {
                LogCommand(cmd, ero);
                CloseConn(true);
                throw ero;
            }
            GetOutPutValue(cmd);
            CloseConn();
            return a;
        }
        private async Task<object> ExecuteScalarAsync(string text, CommandType type)
        {
            var time = DateTime.Now;
            GetOrCreateConn();
            DbCommand cmd = (DbCommand)CreateCmd(text, currentConn);
            if (_trans != null)
            {
                cmd.Transaction = _trans as DbTransaction;
            }
            FillCmdParams(cmd);
            cmd.CommandType = type;
            object a = null;
            try
            {
                a = await cmd.ExecuteScalarAsync();
                GetOutPutValue(cmd);
                var ts = DateTime.Now - time;
                ExecuteTime += ts.TotalMilliseconds;
            }
            catch (Exception ero)
            {
                LogCommand(cmd, ero);
                CloseConn(true);
                throw ero;
            }
            CloseConn();
            return a;
        }

        private async Task<DbDataReader> ExecuteReaderAsync(string text, CommandType type)
        {
            var time = DateTime.Now;
            GetOrCreateConn();
            getOutPutValue = false;
            CurrentCommand = null;
            CurrentCommand = CreateCmd(text, currentConn);
            CurrentCommand.Transaction = _trans as DbTransaction;
            CurrentCommand.CommandType = type;
            FillCmdParams(CurrentCommand);
            DbDataReader r;
            try
            {
                r = await ((DbCommand)CurrentCommand).ExecuteReaderAsync(AutoCloseConn ? CommandBehavior.CloseConnection : CommandBehavior.Default);
                //GetOutPutValue(CurrentDataReadCommand);
                var ts = DateTime.Now - time;
                ExecuteTime += ts.TotalMilliseconds;
            }
            catch (Exception ero)
            {
                LogCommand(CurrentCommand, ero);
                CloseConn(true);
                throw ero;
            }
            return r;
        }
        #endregion

        //public virtual Task InsertFromDataTableAsync(DataTable dataTable, string tableName, bool keepIdentity = false)
        //{
        //    throw new NotImplementedException();
        //}

        /// <summary>
        /// 执行一条sql语句，返回影响行数
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <returns></returns>
        public async Task<int> ExecuteAsync(string sql)
        {
            return await ExecuteNonQueryAsync(sql, CommandType.Text);
        }

        /// <summary>
        /// 执行一条sql语句，返回DbDataReader
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <returns></returns>
        public async Task<DbDataReader> ExecDataReaderAsync(string sql)
        {
            return await ExecuteReaderAsync(sql, CommandType.Text);
        }

        /// <summary>
        /// 执行一条sql语句，返回首行首列
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <returns></returns>
        public async Task<object> ExecScalarAsync(string sql)
        {
            return await ExecuteScalarAsync(sql, CommandType.Text);
        }

        public async Task<DbDataReader> RunDataReaderAsync(string sp)
        {
            return await ExecuteReaderAsync(sp, CommandType.StoredProcedure);
        }
    }
}
